﻿using System;
using System.Text;
using System.Xml;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Utilities;
using System.Diagnostics;

namespace SharePointOfView.SPReporting.Jobs
{
    public class GenericReportingJobDefinition : SPJobDefinition
    {
        private int jobProgressState;

        /// <summary>
        /// Default constructor. Do not use.
        /// </summary>
        public GenericReportingJobDefinition()
        {
        }

        /// <summary>
        /// Initializes a new GenericReportingJobDefinition instance
        /// </summary>
        /// <param name="jobName">Job's internal name</param>
        /// <param name="jobDisplayName">Job's display name</param>
        /// <param name="reportName">Job's report filename</param>
        /// <param name="lockType">Job Lock Type</param>
        public GenericReportingJobDefinition(string jobName, string jobDisplayName, string reportName, SPJobLockType lockType)
            : base(jobName, SPFarm.Local.Services.GetValue<SPTimerService>(Globals.SPTimerServiceName), null, lockType)
        {
            // Assign displayname as job's title
            Title = jobDisplayName;
            ReportName = reportName;
        }

        /// <summary>
        /// Report Filename
        /// </summary>
        public string ReportName
        {
            get { return Properties["ReportName"] as string; }
            set { Properties["ReportName"] = value; }
        }

        /// <summary>
        /// Gather data defined by the job and save it as an XML file using the Report Name
        /// </summary>
        /// <param name="targetInstanceId"></param>
        public override void Execute(Guid targetInstanceId)
        {
            // TODO : throw exception
            if (string.IsNullOrEmpty(Utilities.ReportsCenterUrl))
            {
                Debug.Write("Reports Center Url is null or empty", "SharePointOfView.SPReporting.Jobs.GenericReportingJobDefinition.Execute");
                return;
            }

            // Initializes a new XML document with the gathered data
            XmlDocument xmlDocument = GatherData();

            // Retrieve the reports library Url
            string reportsDocLibUrl = Utilities.GetResourceString("SoVSPReportingLists_ReportingReportsList_Url");

            // Get admin site collection
            using (SPSite site = new SPSite(Utilities.ReportsCenterUrl))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    // Check if the dependant feature is activated
                    if (Utilities.IsReportsCenter(web))
                    {
                        // Retrieve reports document library to add our new report
                        SPDocumentLibrary reportsDocLib = web.GetList(SPUrlUtility.CombineUrl(web.ServerRelativeUrl, reportsDocLibUrl)) as SPDocumentLibrary;
                        // Allow Unsafe Updates is added there to support direct launch from the web UI
                        web.AllowUnsafeUpdates = true;
                        reportsDocLib.RootFolder.Files.Add(ReportName, Encoding.UTF8.GetBytes(xmlDocument.OuterXml), true);
                        web.AllowUnsafeUpdates = false;
                    }
                    else
                    {
                        Debug.Write("Error : Missing feature", "SharePointOfView.SPReporting.Jobs.GenericReportingJobDefinition.Execute");
                        throw new Exception("Missing feature");
                    }
                }
            }
        }

        /// <summary>
        /// Update the progress status by adding %
        /// </summary>
        /// <param name="percentage">Percentage to add</param>
        public void AddProgress(int percentage)
        {
            jobProgressState += percentage;
            if (jobProgressState > 100) jobProgressState = 100;
            UpdateProgress(jobProgressState);
        }

        /// <summary>
        /// Return an XmlDocument contains all the data gathered
        /// </summary>
        /// <returns>XML document containing all the data gathered.</returns>
        public virtual XmlDocument GatherData()
        {
            throw new Exception("You must override this method");
        }
    }
}